package com.ccys.netty.service;

import com.alibaba.fastjson.JSONObject;
import com.ccys.netty.config.NettyConfig;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.stereotype.Component;

import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;

   /**
    * @description redis订阅 发布的消息会自动接收到此类（redis发布订阅topic）
    * @date     2024/2/29
    * @author   cloud fly
    */
@Component
@Slf4j
public class MessageReceive {

    /**
     * 订阅消息,发送给指定用户
     * @param str
     */
    public void getMessageToOne(String str) {
        log.info(str);
        //["com.alibaba.fastjson.JSONObject",{"msg":"你好，这是服务发送的消息","userId":"214365"}]
        Object[] data = JSONObject.parseArray(str).toArray();
        JSONObject json = (JSONObject) data[1];
        System.out.println("订阅消息,发送给指定用户：" + json.getString("msg"));

        // 推送消息
        String message = json.getString("msg");
        String userId = json.getString("userId");

        ConcurrentHashMap<String, ChannelHandlerContext> userChannelMap = NettyConfig.getUserChannelMap();
        ChannelHandlerContext channel = userChannelMap.get(userId);
        if(!Objects.isNull(channel)){
            // 如果该用户的客户端是与本服务器建立的channel,直接推送消息
            channel.writeAndFlush(new TextWebSocketFrame(message));
        }
    }

    /**
     * 订阅消息，发送给所有用户
     * @param object
     */
    public void getMessageToAll(String object) {
        Jackson2JsonRedisSerializer serializer = getSerializer(String.class);
        String message = (String) serializer.deserialize(object.getBytes());
        System.out.println("订阅消息，发送给所有用户：" + message);
        NettyConfig.getChannelGroup().writeAndFlush(new TextWebSocketFrame(message));
    }

    private Jackson2JsonRedisSerializer getSerializer(Class clazz){
        //序列化对象（特别注意：发布的时候需要设置序列化；订阅方也需要设置序列化）
        Jackson2JsonRedisSerializer seria = new Jackson2JsonRedisSerializer(clazz);
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        seria.setObjectMapper(objectMapper);
        return seria;
    }




}

